/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
 * Description: DDR driver APIs
 * Author: l00416998
 * Create: 2018-05-10
 */
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include "bd_info.h"

static unsigned long get_ddr_size(void)
{
    bdinfo_init();
    return bdinfo_get_ddr_size();
}

static u32 get_ddr_ecc_state(void)
{
    bdinfo_init();
    return bdinfo_get_ddr_ecc();
}

unsigned long get_ramdisk_size(void)
{
#ifdef IBMC_RAMDISK_SIZE
    return IBMC_RAMDISK_SIZE;
#endif

    return 0;
}

unsigned long get_ddr_rsv_size(void)
{
    return IBMC_SYS_RSV_SIZE + get_ramdisk_size();
}

int dram_init_banksize(void)
{
    unsigned char *spin_table_addr = (unsigned char *)CPU_RELEASE_ADDR;
    unsigned long ddr_size;
    unsigned long ddr_rsv_size;
    unsigned long ddr_ecc_size = 0;

    ddr_rsv_size = get_ddr_rsv_size();

    ddr_size = get_ddr_size();

    /* 计算ecc空间 */
    if (get_ddr_ecc_state()) {
        ddr_ecc_size = ddr_size >> 3; /* ecc开启, 右移3位 1/8空间是计算ecc空间 */
    }

    gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
    gd->bd->bi_dram[0].size = (ddr_size - ddr_rsv_size) - ddr_ecc_size;

    (void)memset(spin_table_addr, 0, CPU_RELEASE_ADDR_LEN);

    return 0;
}

int dram_init(void)
{
    unsigned long ddr_size;
    unsigned long ddr_rsv_size;
    unsigned long ddr_ecc_size = 0;

    ddr_rsv_size = get_ddr_rsv_size();

    ddr_size = get_ddr_size();

    /* 计算ecc空间 */
    if (get_ddr_ecc_state()) {
        ddr_ecc_size = ddr_size >> 3; /* ecc开启, 右移3位 1/8空间是计算ecc空间 */
    }

    gd->ram_size = (ddr_size - ddr_rsv_size) - ddr_ecc_size;

    return 0;
}
